﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Security.Cryptography;
using System.Web;
using System.IO;
using System.Net;

namespace zichan
{
   public class XmispAuth
    {
       static string m_HeadKey, m_Key;

       public XmispAuth(string strHKey, string strKey)
       {
           m_HeadKey = strHKey;
           m_Key = strKey;
       }

       public string Post(Dictionary<string, string> kv, string url)
       {
           kv.Add("Format", "JSON");
           kv.Add("Version", "1.0");
           kv.Add("TimeStamp", TimeStamp().ToString());
           kv.Add("Signature", Sign(kv));
           string postdate = KvToStr(kv);

           string result;
            try
            {
                HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
               request.ContentType = "application/x-www-form-urlencoded";
               request.Headers.Add(m_HeadKey);
               request.Method = "post";
               request.AllowAutoRedirect = false;
               request.ContentType = "application/x-www-form-urlencoded;charset=gbk";
               //request.CookieContainer = new CookieContainer();
               request.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.11 (KHTML, like Gecko) Chrome/23.0.1271.95 Safari/537.11";
               byte[] buffer = Encoding.GetEncoding("utf-8").GetBytes(postdate);
               request.ContentLength = buffer.Length;
               request.GetRequestStream().Write(buffer, 0, buffer.Length);
               HttpWebResponse response = (HttpWebResponse)request.GetResponse();
               using (StreamReader sr =new StreamReader( response.GetResponseStream(),Encoding.UTF8)) {
                  result= sr.ReadToEnd();
               }
            }
            catch (WebException ex)
            {
                var rsp = ex.Response as HttpWebResponse;
                using (StreamReader sr = new StreamReader(rsp.GetResponseStream(), Encoding.UTF8))
                {
                    result = sr.ReadToEnd();
                }
            }
            return result;
       }


       /// <summary>
       /// php时间戳
       /// </summary>
       /// <returns></returns>
       public long TimeStamp()
       {
           DateTime timeStamp = new DateTime(1970, 1, 1);  //得到1970年的时间戳  
           return (DateTime.UtcNow.Ticks - timeStamp.Ticks) / 10000000;  //注意这里有时区问题，用now就要减掉8个小时  
       }


       public object hash_hmac(string signatureString, string secretKey, bool raw_output = false)
       {
           var enc = Encoding.UTF8;
           HMACSHA1 hmac = new HMACSHA1(enc.GetBytes(secretKey));
           hmac.Initialize();

           byte[] buffer = enc.GetBytes(signatureString);
           if (raw_output)
               return hmac.ComputeHash(buffer);
           else
               return BitConverter.ToString(hmac.ComputeHash(buffer)).Replace("-", "").ToUpper();
       }

        public  string KvToStr(Dictionary<string, string> kvs)
        {
            StringBuilder sb = new StringBuilder();
            var cs = kvs.OrderBy(o => o.Key, new StringComparer()).ToList();
            foreach (var c in cs)
                sb.AppendFormat("&{0}={1}", UrlEncode(c.Key), UrlEncode(c.Value));

            return sb.ToString().TrimStart('&');
        }

        public string Sign(Dictionary<string, string> kvs)
        {
            string str = KvToStr(kvs);
            string nstr = "GET&%2F&" + UrlEncode(str);
            string ss = nstr.Replace("%7E", "~");
            return Convert.ToBase64String((byte[])hash_hmac(ss, m_Key + "&", true));
        }

        /// <summary>
        /// url编码(结果大写)
        /// </summary>
        /// <param name="temp"></param>
        /// <returns></returns>
        public  string UrlEncode(string temp)
        {
            System.Text.Encoding encoding = System.Text.Encoding.GetEncoding("utf-8");
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < temp.Length; i++)
            {
                string t = temp[i].ToString();
                string k = HttpUtility.UrlEncode(t, encoding);
                if (t == k)
                    stringBuilder.Append(t);
                else
                    stringBuilder.Append(k.ToUpper());
            }
            return stringBuilder.ToString();
        }


        /// <summary>
        /// 按字符串排序 区分大小写
        /// </summary>
        public class StringComparer : IComparer<string>
        {
            public int Compare(string x, string y)
            {
                if (x == y)
                    return 0;
                if (string.IsNullOrEmpty(x))
                    return -1;

                if (string.IsNullOrEmpty(y))
                    return 1;

                int l = y.Length;
                for (int i = 0; i < x.Length; i++)
                {
                    if (i < l)
                    {
                        if (x[i] > y[i])
                            return 1;
                        else if (x[i] < y[i])
                            return -1;
                    }
                    else
                        return 1;
                }
                return 0;
            }
        }
    }
}
